; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s

define void @test(ptr %P, ptr %Q, i1 %A, i1 %B) {
; CHECK-LABEL: @test(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[A_NOT:%.*]] = xor i1 [[A:%.*]], true
; CHECK-NEXT:    [[BRMERGE:%.*]] = select i1 [[A_NOT]], i1 true, i1 [[B:%.*]]
; CHECK-NEXT:    br i1 [[BRMERGE]], label [[B:%.*]], label [[COMMON_RET:%.*]]
; CHECK:       common.ret:
; CHECK-NEXT:    ret void
; CHECK:       b:
; CHECK-NEXT:    store i32 123, ptr [[P:%.*]], align 4
; CHECK-NEXT:    br label [[COMMON_RET]]
;

entry:
  br i1 %A, label %a, label %b
a:
  br i1 %B, label %b, label %c
b:
  store i32 123, ptr %P
  ret void
c:
  ret void
}

; rdar://10554090
define zeroext i1 @test2(i64 %i0, i64 %i1) nounwind uwtable readonly ssp {
; CHECK-LABEL: @test2(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[AND_I_I:%.*]] = and i64 [[I0:%.*]], 281474976710655
; CHECK-NEXT:    [[AND_I11_I:%.*]] = and i64 [[I1:%.*]], 281474976710655
; CHECK-NEXT:    [[OR_COND:%.*]] = icmp eq i64 [[AND_I_I]], [[AND_I11_I]]
; CHECK-NEXT:    br i1 [[OR_COND]], label [[C:%.*]], label [[A:%.*]]
; CHECK:       a:
; CHECK-NEXT:    [[SHR_I4_I:%.*]] = lshr i64 [[I0]], 48
; CHECK-NEXT:    [[AND_I5_I:%.*]] = and i64 [[SHR_I4_I]], 32767
; CHECK-NEXT:    [[SHR_I_I:%.*]] = lshr i64 [[I1]], 48
; CHECK-NEXT:    [[AND_I2_I:%.*]] = and i64 [[SHR_I_I]], 32767
; CHECK-NEXT:    [[CMP9_I:%.*]] = icmp ult i64 [[AND_I5_I]], [[AND_I2_I]]
; CHECK-NEXT:    br i1 [[CMP9_I]], label [[C]], label [[B:%.*]]
; CHECK:       b:
; CHECK-NEXT:    [[SHR_I13_I9:%.*]] = lshr i64 [[I1]], 48
; CHECK-NEXT:    [[AND_I14_I10:%.*]] = and i64 [[SHR_I13_I9]], 32767
; CHECK-NEXT:    [[SHR_I_I11:%.*]] = lshr i64 [[I0]], 48
; CHECK-NEXT:    [[AND_I11_I12:%.*]] = and i64 [[SHR_I_I11]], 32767
; CHECK-NEXT:    [[PHITMP:%.*]] = icmp uge i64 [[AND_I14_I10]], [[AND_I11_I12]]
; CHECK-NEXT:    br label [[C]]
; CHECK:       c:
; CHECK-NEXT:    [[O2:%.*]] = phi i1 [ false, [[A]] ], [ [[PHITMP]], [[B]] ], [ false, [[ENTRY:%.*]] ]
; CHECK-NEXT:    ret i1 [[O2]]
;
entry:
  %and.i.i = and i64 %i0, 281474976710655
  %and.i11.i = and i64 %i1, 281474976710655
  %or.cond = icmp eq i64 %and.i.i, %and.i11.i
  br i1 %or.cond, label %c, label %a

a:
  %shr.i4.i = lshr i64 %i0, 48
  %and.i5.i = and i64 %shr.i4.i, 32767
  %shr.i.i = lshr i64 %i1, 48
  %and.i2.i = and i64 %shr.i.i, 32767
  %cmp9.i = icmp ult i64 %and.i5.i, %and.i2.i
  br i1 %cmp9.i, label %c, label %b

b:
  %shr.i13.i9 = lshr i64 %i1, 48
  %and.i14.i10 = and i64 %shr.i13.i9, 32767
  %shr.i.i11 = lshr i64 %i0, 48
  %and.i11.i12 = and i64 %shr.i.i11, 32767
  %phitmp = icmp uge i64 %and.i14.i10, %and.i11.i12
  br label %c

c:
  %o2 = phi i1 [ false, %a ], [ %phitmp, %b ], [ false, %entry ]
  ret i1 %o2
}

; PR13180
define void @pr13180(i8 %p) {
; CHECK-LABEL: @pr13180(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    unreachable
;
entry:
  %tobool = icmp eq i8 %p, 0
  br i1 %tobool, label %cond.false, label %cond.true

cond.true:                                        ; preds = %entry
  br label %cond.end

cond.false:                                       ; preds = %entry
  %phitmp = icmp eq i8 %p, 0
  br label %cond.end

cond.end:                                         ; preds = %cond.false, %cond.true
  %cond = phi i1 [ undef, %cond.true ], [ %phitmp, %cond.false ]
  unreachable
}

declare void @foo()
define void @test3() {
; CHECK-LABEL: @test3(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    call void @foo()
; CHECK-NEXT:    ret void
;
entry:
  br i1 0, label %bb0, label %bb0

bb0:
  call void @foo()
  ret void
}
